
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <stdio.h>
#include <sys/time.h>
#include "app_platform/cntl_info.h"
#include "app_platform/cgi_stub_cntl.h"
#include "../include/giscoreao_stub4web_allinone.h"
#include "erp/gis/po/shiptypeareagischeckpo_gis.h"	
#include "erp/gis/po/mergedcoordinatespo_gis.h"	
#include <map>	
#include <vector>
#include "erp/comm/erp_cache_client.h"
#include "erp/gis/ddo/shiptypearealocusdolist_gis.h"

using namespace erp::comm;
using namespace erp::gis::ao;

void Init()
{       
	if(CCGI_STUB_CNTL->Initialize(true) != 0)
		std::cerr << "CCGI_STUB_CNTL->Init failed" << std::endl;
	CCGI_STUB_CNTL->setTimeout(30);

	
	
	
}

void TestCmem()
{
	//  shiptype: 12 areaId 310000 expire: 1382490511
	std::string strTmemSvrName ="erp_gis_tmem";
	uint32_t dwTmemBid = 100190;

	const std::map<TmemCacheItilEnum,uint32_t> mapItil;
	int iRet = TMEM_CACHE_OP->Initialize(
			strTmemSvrName,
			dwTmemBid,
			mapItil);
	if (0 != iRet)
	{
		std::cout << "cmem init failed" << std::endl;
		return;
	}

	uint32_t dwCurrTime = time(0);

	erp::gis::po::CShipTypeAreaGisCheckPo shipTypeAreaGisCheckPo;
	//iRet = TMEM_CACHE_OP->AddSimpleData("test_key_xxxxx", shipTypeAreaGisCheckPo, dwCurrTime);
	//iRet = TMEM_CACHE_OP->AddSimpleData("test_key_xxxxy", shipTypeAreaGisCheckPo, dwCurrTime);
	if (0 != iRet)
	{
		std::cout << "add cmem failed" << TMEM_CACHE_OP->GetLastErrMsg() << std::endl;
		return;
	}

	#if 0
	uint32_t dwExpireTime;
	//iRet = TMEM_CACHE_OP->GetSimpleData("test_key_xxxxx", shipTypeAreaGisCheckPo, dwExpireTime);
	#else

	std::vector<std::string> vecKey;
	vecKey.push_back("gis_shiparea_locus_12_310000");
	vecKey.push_back("gis_shiparea_locus_12_310100");
	//vecKey.push_back("test_key_xxxxy");

	std::vector<erp::gis::ddo::CShipTypeAreaLocusDoList> vecObj;
	std::vector<uint32_t> vecExpire;

	CacheFailedKey oFailKey;
	iRet = TMEM_CACHE_OP->GetMulSimpleData(vecKey, vecObj, oFailKey, vecExpire);
	if (0 != iRet)
	{
		std::cout << "get cmem failed" << TMEM_CACHE_OP->GetLastErrMsg() << std::endl;
		return;
	}
	for (int i = 0; i < (int) vecExpire.size(); i++)
	std::cout << " expire" << i << " "<< vecExpire[i] << std::endl;
	
	
	#endif
}



void TestCheckAreaCover()
{
	//TODO 如果使用配置中心来获取APP地址,请注释下行
	CCGI_STUB_CNTL->setPeerAddr("10.12.192.209", 53101);

	//TODO 请设置用户Passport
	CCntlInfo oCntlInfo;
	oCntlInfo.setOperatorUin(88883687);
	oCntlInfo.setOperatorClientIP(0);
	oCntlInfo.setOperatorKey("stw3ymf9uk");
	//TODO 请设置路由值
	oCntlInfo.setRouteKey(88883687);
	std::string machineKey = "shellex";		
	std::string source = "shellex";		
	uint32_t sceneId = 0;
	erp::gis::po::CShipTypeAreaGisCheckPo shipTypeAreaGisCheckPo;
    std::vector<uint32_t>  vecShipType;
    vecShipType.push_back(1);
    vecShipType.push_back(12);
    shipTypeAreaGisCheckPo.SetShipType(vecShipType);
    shipTypeAreaGisCheckPo.SetDestGbCityId(310100);
    shipTypeAreaGisCheckPo.SetDestGbProvinceId(310000);
    shipTypeAreaGisCheckPo.SetDestAddrProvince("上海");
    shipTypeAreaGisCheckPo.SetDestAddrCity("上海市");
    shipTypeAreaGisCheckPo.SetDestAddrDistrict("奉贤区");
    shipTypeAreaGisCheckPo.SetDestAddrText("海思路999号");

	std::string inReserve = "";		
	std::map<uint32_t,uint32_t > CheckResult;
	std::string errMsg = "";		
	std::string outReserve = "";		
	CGisCoreAoStub4Web oStub;
	// TODO:替换函数参数
    uint32_t dwResult = oStub.CheckAreaCover(
		oCntlInfo,
		machineKey,
		source,
		sceneId,
		shipTypeAreaGisCheckPo,
		inReserve,
		CheckResult,
		errMsg,
		outReserve
  	);
    if(dwResult == 0)
	{
		std::cout << "Invoke OK!" << std::endl;
		printf("OK result[0x%x], time = %ld\n"
        , dwResult, oStub.GetLastConsumeTime());
	    std::map<uint32_t,uint32_t >::iterator iter =  CheckResult.begin();
        for(;iter != CheckResult.end(); ++ iter)
        {
            std::cout << "shiptype: " << iter->first << " result: " << iter->second << std::endl;
        }

	}
	else
    {
        printf("Error result[0x%x], time = %ld , errmsg = [%s]\n"
        , dwResult, oStub.GetLastConsumeTime(),oStub.GetLastErrMsg());
    }
}
void TestGetMergeCoordinate()
{
	//TODO 如果使用配置中心来获取APP地址,请注释下行
	//CCGI_STUB_CNTL->setPeerAddr("172.25.34.123", 53101);

	//TODO 请设置用户Passport
	CCntlInfo oCntlInfo;
	oCntlInfo.setOperatorUin(88883687);
	oCntlInfo.setOperatorClientIP(0);
	oCntlInfo.setOperatorKey("stw3ymf9uk");
	//TODO 请设置路由值
	oCntlInfo.setRouteKey(88883687);
	std::string machineKey = "test";		
	std::string source = "test";		
	uint32_t sceneId = 0;
	std::string destAddrProvince = "广东省";		
	std::string destAddrCity = "深圳市";		
	std::string destAddrDistrict = "南山区";		
	std::string destAddrText = "腾讯大厦1";		
	std::string inReserve = "";		
	erp::gis::po::CMergedCoordinatesPo mergedCoordinatesPo;
	std::string errMsg = "";		
	std::string outReserve = "";		
	CGisCoreAoStub4Web oStub;
	// TODO:替换函数参数
    uint32_t dwResult = oStub.GetMergeCoordinate(
		oCntlInfo,
		machineKey,
		source,
		sceneId,
		destAddrProvince,
		destAddrCity,
		destAddrDistrict,
		destAddrText,
		inReserve,
		mergedCoordinatesPo,
		errMsg,
		outReserve
  	);
    if(dwResult == 0)
	{
		std::cout << "Invoke OK!" << std::endl;
		printf("OK result[0x%x], time = %ld\n"
        , dwResult, oStub.GetLastConsumeTime());
		
		std::cout << "x:" << mergedCoordinatesPo.GetXPoint() << std::endl;
		std::cout << "y:" << mergedCoordinatesPo.GetYPoint() << std::endl;
		std::cout << "level:" << mergedCoordinatesPo.GetTrustLevel() << std::endl;
	}
	else
    {
        printf("Error result[0x%x], time = %ld , errmsg = [%s]\n"
        , dwResult, oStub.GetLastConsumeTime(),oStub.GetLastErrMsg());
    }
}


#include <cmath>
const static double PI           = 3.14159265f;
const static double EARTH_RADIUS = 6378.137f;
void GetEarthDistance(
				double dbX1,
				double dbY1,
				double dbX2,
				double dbY2)
{
	double dbTmp = 0;

	double dbX1_radius = dbX1 * PI / 180.0;
	double dbY1_radius = dbY1 * PI / 180.0;
	double dbX2_radius = dbX2 * PI / 180.0;
	double dbY2_radius = dbY2 * PI / 180.0;

	double dbX12_distance = dbX1_radius - dbX2_radius;
	double dbY12_distance = dbY1_radius - dbY2_radius;

	double dbX12_sin_pow = pow(sin(dbX12_distance/2.0), 2); // power of sin(a/2)
	double dbY12_sin_pow = pow(sin(dbY12_distance/2.0), 2); // power of sin(b/2)

	double dbY1_cos = cos(dbY1_radius);
	double dbY2_cos = cos(dbY2_radius);

	dbTmp = 2 * EARTH_RADIUS * asin(sqrt(dbY12_sin_pow + dbY1_cos * dbY2_cos * dbX12_sin_pow));
	dbTmp = round(dbTmp * 100000) / 100000;
	dbTmp = dbTmp * 1000;

	std::cout << "distance:" << dbTmp << std::endl;
}


uint64_t getTimeMs()
{
	struct timeval tvTime; 
    gettimeofday(&tvTime, NULL);

    return (tvTime.tv_sec*1000000 + tvTime.tv_usec);
}


//测试主函数
int main(int argc, char** argv)
{
	//
	//测试主流程
	// 开发人员可以根据业务需要进行顺序的调整，以期达到更好的测试效果
	// 比如，可以按照插入、选择、修改、选择、删除、选择 顺序进行处理
	//
	Init();

	//TestCmem();

	//GetEarthDistance(atof(argv[1]), atof(argv[2]), atof(argv[3]), atof(argv[4])); 

	uint64_t ddwStart = getTimeMs();
	
	TestCheckAreaCover();
	//TestGetMergeCoordinate();

	uint64_t ddwEnd = getTimeMs();
	std::cout << "time:" << ddwEnd - ddwStart << std::endl;
	
	return 0;
}

